/*
	Adobe Systems Incorporated(r) Source Code License Agreement
	Copyright(c) 2007 Adobe Systems Incorporated. All rights reserved.
	
	Please read this Source Code License Agreement carefully before using
	the source code.
	
	Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, 
	no-charge, royalty-free, irrevocable copyright license, to reproduce,
	prepare derivative works of, publicly display, publicly perform, and
	distribute this source code and such derivative works in source or 
	object code form without any attribution requirements.  
	
	The name "Adobe Systems Incorporated" must not be used to endorse or promote products
	derived from the source code without prior written permission.
	
	You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
	against any loss, damage, claims or lawsuits, including attorney's 
	fees that arise or result from your use or distribution of the source 
	code.
	
	THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT 
	ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
	FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ALSO, THERE IS NO WARRANTY OF 
	NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT.  IN NO EVENT SHALL ADOBE
	OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
	OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import com.adobe.apps.ascension.ISongListenable;
import com.adobe.apps.ascension.MP3Player;
import com.adobe.apps.ascension.Song;
import com.adobe.apps.ascension.events.ImportEvent;
import com.adobe.apps.ascension.events.MP3PlayerEvent;
import com.adobe.apps.ascension.events.MediaPlayRequestEvent;
import com.adobe.apps.ascension.events.PlayerControlEvent;
import com.adobe.apps.ascension.importers.ItunesLibraryParser;
import com.adobe.apps.ascension.tree.AlbumArtNode;
import com.adobe.apps.ascension.tree.RelatedTreeNode;
import com.adobe.apps.ascension.tree.TreeNode;
import com.adobe.apps.ascension.tree.YouTubeTreeNode;

import controls.ITunesImportPanel;
import controls.AboutBox;
import controls.PlayerControls;
import controls.content.AscensionLibraryView;
import controls.content.SongLibraryView;
import controls.visualizers.BubblesSpectrum;
import controls.visualizers.CircleVisualizer;
import controls.visualizers.FlickrVisualizer;
import controls.visualizers.LineVisualizer;

import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;

import mx.binding.utils.BindingUtils;
import mx.binding.utils.ChangeWatcher;
import mx.collections.ArrayCollection;
import mx.controls.Menu;
import mx.core.IFlexDisplayObject;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.events.MenuEvent;
import mx.events.PropertyChangeEvent;
import mx.events.TreeEvent;
import mx.managers.PopUpManager;
//import com.adobe.apps.ascension.tree.LyricWikiTreeNode;
import com.adobe.apps.ascension.Library;
import com.adobe.apps.ascension.events.LibraryEvent;
import flash.html.HTMLControl;
import controls.visualizers.SmileySpectrum;
import flash.events.IOErrorEvent;
import com.adobe.apps.ascension.proxy.ExternalComponentProxy;
import flash.events.SecurityErrorEvent;
import com.adobe.apps.ascension.events.ExternalComponentProxyEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import com.adobe.apps.ascension.proxy.StatusMessage;
import controls.visualizers.IVisualizer;
import com.adobe.apps.ascension.SongMetaDataPopulator;
import flash.display.StageQuality;
import controls.visualizers.AlbumArtVisualizer;
import com.adobe.apps.ascension.tree.LyricWikiTreeNode;
import mx.controls.Tree;
import controls.SettingsView;
import com.adobe.apps.ascension.events.SettingsEvent;
import com.adobe.apps.ascension.utils.URLCache;
import com.adobe.apps.ascension.utils.AscensionCacheEnum;
import com.adobe.apps.ascension.tree.ArtistInfoNode;
import com.adobe.apps.ascension.Settings;
import flash.net.FileReference;
import flash.filesystem.File;
import flash.filesystem.FileStream;
import flash.filesystem.FileMode;
import flash.net.registerClassAlias;
import com.adobe.apps.ascension.events.AlbumViewEvent;
import com.adobe.apps.ascension.tree.AlbumInfoNode;
import com.adobe.apps.ascension.tree.SongInfoNode;
import controls.visualizers.Perlin1;
import controls.visualizers.Perlin2;
import controls.visualizers.PerlinVisualizerBase;
import flash.net.URLRequestMethod;
import controls.visualizers.AMSpectrum;
import controls.TipsView;
import com.adobe.apps.ascension.tips.LocalTipManager;
import com.adobe.apps.ascension.tips.TipEvent;


private var player:MP3Player = new MP3Player();
private var songView:AscensionLibraryView;
//private var itunesView:ItunesLibraryView;

private var currentSongDP:ArrayCollection;

private var proxy:ExternalComponentProxy;

//todo: make this a preference
private const BACK_LIMIT:Number = 2000;

//todo: preference
private var connectToProxy:Boolean = true;

//todo: preference
private var proxyURL:String = "localhost";

//todo: preference
private var port:int = 8999;

private var albumNode:TreeNode;

private var settingsName:String = "settings";

public static var settings:Settings;

private var songNotiferArray:Array;

private const TIPS_DIR_NAME:String = "tips";

[Embed(source='/assets/menuicons/ipod_cast_add.png')]
public var itunesImportIcon:Class;	

[Embed(source='/assets/treeicons/chart_line.png')]
private var lineIcon:Class;
	
[Embed(source='/assets/treeicons/chart_curve.png')]
private var amsIcon:Class;			

[Embed(source='/assets/treeicons/library.png')]
private var tableIcon:Class;
	
[Embed(source='/assets/treeicons/bubbles.png')]
private var bubblesIcon:Class;						

[Embed(source='/assets/treeicons/flickr_icon.png')]
private var flckrIcon:Class;			

[Embed(source='/assets/visualizers/emoticon_grin.png')]
private var smiley:Class;		

[Embed(source='/assets/treeicons/blue_circle.png')]
private var circleIcon:Class;	

[Embed(source='/assets/treeicons/album_art_icon.png')]
private var albumArtIcon:Class;				

[Bindable]
public var currentSong:Song;

private var library:Library;

private var visualizers:ArrayCollection;


private function onLayoutComplete():void
{
	stage.window.visible=true;
}

private function onCreationComplete():void
{	
	registerClassAlias("com.adobe.apps.ascension.Settings", Settings);
	settings = loadSettings();
	
	systemManager.stage.window.width = 950;
	systemManager.stage.window.height = 450;	
	systemManager.stage.quality = StageQuality.BEST;
	
	setUpListeners();
	
	songView = new AscensionLibraryView();
	
	songView.addEventListener(MediaPlayRequestEvent.SONGPLAYREQUEST, onPlaySongRequest);
	songView.addEventListener(SongLibraryView.ITUNES_IMPORT, onItunesImport);
	
	
	initializeTree();			
					
	contentContainer.currentView = songView;
	songProgress.player = player;
	
	library = new Library();
	library.addEventListener(LibraryEvent.LIBRARY_LOADED, onLibraryLoad);
	library.addEventListener(IOErrorEvent.IO_ERROR, onLibraryLoadFail);
		
	library.load();
	
	volumeControl.player = player;
	player.volume = 0.5;
	
	initializeProxy();
	
	if(settings.showTipsOnStart)
	{
		displayTips();
	}
}	

private function loadSettings():Settings
{
	var f:File = File.appStorageDirectory.resolve(settingsName);
	
	if(!f.exists)
	{
		return new Settings();
	}
	
	var fs:FileStream = new FileStream();
		fs.open(f, FileMode.READ);
		
	var out:Settings = fs.readObject() as Settings;
	
	fs.close();
	
	return out;
}

private function saveSettings():void
{
	var f:File = File.appStorageDirectory.resolve(settingsName);
	
	var fs:FileStream = new FileStream();
		fs.open(f, FileMode.WRITE);
		
		fs.writeObject(settings);
	
	fs.close();
}

private function initializeProxy():void
{
	if(!connectToProxy)
	{
		return;
	}
	
	proxy = new ExternalComponentProxy();
	
	proxy.addEventListener(Event.CLOSE, onProxyClose);
	proxy.addEventListener(Event.CONNECT, onProxyConnect);
	proxy.addEventListener(IOErrorEvent.IO_ERROR, onProxyIOError);
	proxy.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onProxySecurityError);
	
	proxy.addEventListener(ExternalComponentProxyEvent.TOGGLE_PLAY_MODE, onProxyTogglePlay);
	proxy.addEventListener(ExternalComponentProxyEvent.NEXT_SONG, onProxyNextSong);
	proxy.addEventListener(ExternalComponentProxyEvent.PREVIOUS_SONG, onProxyPrevSong);
	proxy.addEventListener(ExternalComponentProxyEvent.SET_POSITION, onProxySetPosition);
	proxy.addEventListener(ExternalComponentProxyEvent.SET_VOLUME, onProxySetVolume);
	proxy.addEventListener(ExternalComponentProxyEvent.NEXT_VISUALIZER, onProxyNextVisualizer);
	proxy.addEventListener(ExternalComponentProxyEvent.PREV_VISUALIZER, onProxyPrevVisualizer);
	
	proxy.socketURL = proxyURL;
	proxy.port = port;
	proxy.connect();
}

private function onCurrentSongChange():void
{
	sendProxyUpdate(true);
}

private var proxyUpdateTimer:Timer;
//todo: preference?
private var PROXY_UPDATE_INTEVAL:Number = 1000;


private function startProxyTimer():void
{
	stopProxyTimer();
	if(proxyUpdateTimer == null)
	{
		proxyUpdateTimer = new Timer( PROXY_UPDATE_INTEVAL );
		proxyUpdateTimer.addEventListener( TimerEvent.TIMER, onProxyTimer );                                                    
	}
	proxyUpdateTimer.start();	
}

private function stopProxyTimer():void
{
	
    if( proxyUpdateTimer != null )
    {
        proxyUpdateTimer.reset();
    }
}

private function onProxyTimer(event:TimerEvent):void
{
	sendProxyUpdate();
}

//changed to default to send song data with every update.
private function sendProxyUpdate(sendSongInfo:Boolean = true):void
{
	var s:StatusMessage = new StatusMessage();
		s.playMode = (player.playing)?StatusMessage.PLAY:StatusMessage.PAUSE;
		s.position = player.position;
		s.songLength = player.length;
		
		var currentView:UIComponent = contentContainer.currentView;
		
		s.visualizerName = (getVisualizerPosition(currentView) != -1)?IVisualizer(currentView).visualizerName:"";
		s.volume = player.volume;
		
		if(sendSongInfo)
		{
			s.song = currentSong;
		}
		
	proxy.sendStatus(s);
}

private function onProxyClose(event:Event):void
{
	//todo: stop timer
	stopProxyTimer();
	proxy.close();
}

private function onProxyConnect(event:Event):void
{
	//connected
	//todo: Start Timer	
	startProxyTimer();
}

private function onProxyIOError(event:IOErrorEvent):void
{
	//error
	proxy.close();
	stopProxyTimer();
}

private function onProxySecurityError(event:SecurityErrorEvent):void
{
	//error
	proxy.close();
	stopProxyTimer();
}

private function onProxyNextSong(event:ExternalComponentProxyEvent):void
{
	playNextSong(true);
}

private function onProxyPrevSong(event:ExternalComponentProxyEvent):void
{
	playPreviousSong();
}

private function onProxySetPosition(event:ExternalComponentProxyEvent):void
{
	player.position = event.position;
}

private function onProxyNextVisualizer(event:ExternalComponentProxyEvent):void
{
	var pos:int = getVisualizerPosition(contentContainer.currentView);
	var nVis:UIComponent;
	
	if(pos == -1 ||
		pos == (visualizers.length - 1))
	{
		nVis = UIComponent(visualizers.getItemAt(0));
	}
	else
	{
		nVis = UIComponent(visualizers.getItemAt(pos + 1));
	}
	
	contentContainer.currentView = nVis;
}

private function onProxyPrevVisualizer(event:ExternalComponentProxyEvent):void
{
	var pos:int = getVisualizerPosition(contentContainer.currentView);
	var nVis:UIComponent;
	
	if(pos == -1)
	{
		nVis = UIComponent(visualizers.getItemAt(0));
	}
	else if (pos == 0)
	{
		nVis = UIComponent(visualizers.getItemAt(visualizers.length - 1));
	}
	else
	{
		nVis = UIComponent(visualizers.getItemAt(pos - 1));
	}
	
	contentContainer.currentView = nVis;	
}

private function getVisualizerPosition(view:UIComponent):int
{
	var len:int = visualizers.length;
	
	for(var i:int = 0; i < len; i++)
	{
		if(visualizers.getItemAt(i) == view)
		{
			return i;
		}
	}
	
	return -1;
}

private function onProxySetVolume(event:ExternalComponentProxyEvent):void
{
	player.volume = event.volume;
}

private function onProxyTogglePlay(event:ExternalComponentProxyEvent):void
{	
	if(player.playing)
	{
		player.pause();
	}
	else
	{
		playOrResumeSong();
	}
}

private function onLibraryLoadFail(event:IOErrorEvent):void
{
	trace("Failed to load library : " + event.text);
}

private function onLibraryLoad(event:LibraryEvent):void
{
	songView.dataProvider = library.songs;
}

private function registerForCurrentSong(sl:ISongListenable):void
{
	if(songNotiferArray == null)
	{
		songNotiferArray = new Array();
		ChangeWatcher.watch(this, "currentSong", onChangeCurrentSong);
	}
	songNotiferArray.push(sl);
}

private function onChangeCurrentSong(event:PropertyChangeEvent):void
{
	for each(var item:ISongListenable in songNotiferArray)
	{
		item.song = currentSong;
	}	
	
	if(proxy.connected)
	{
		sendProxyUpdate(true);
	}
}

private function initializeTree():void
{
	var ac:ArrayCollection = new ArrayCollection();
			
		var libNode:TreeNode =  new TreeNode("Library", songView);
			

			
			libNode.icon = tableIcon;
			//songs.children.addItem(new TreeNode("iTunes", itunesView));
			
			
		var exploreNode:TreeNode = new TreeNode("Explore");
			exploreNode.children = new ArrayCollection();	
			
		var visNodes:TreeNode = new TreeNode("Visualizations");
		var ams:AMSpectrum = new AMSpectrum();
		visNodes.children = new ArrayCollection();
		
		
		
		
		/* AMS Spectrum Node */
		var amsNode:TreeNode = new TreeNode("AMSpectrum", ams);
			amsNode.icon = amsIcon;

		visNodes.children.addItem(amsNode);
		
		var bubbles:BubblesSpectrum = new BubblesSpectrum();
		var bubblesNode:TreeNode = new TreeNode("Bubbles", bubbles);
			bubblesNode.icon = bubblesIcon;
		visNodes.children.addItem(bubblesNode);
		
		visualizers = visNodes.children;
		
		

		
		/* Line Visualizer Node */
		var lVis:LineVisualizer = new LineVisualizer();
		var lvNode:TreeNode = new TreeNode("Lines", lVis);
			lvNode.icon = lineIcon;			
		
		
		visNodes.children.addItem(lvNode);
		
		
		/* Smiley Node */
		var smile:SmileySpectrum = new SmileySpectrum();
		var smileNode:TreeNode = new TreeNode("Smiley", smile);
	
		smileNode.icon = smiley;
		
		visNodes.children.addItem(smileNode);

		
		var p1Vis:Perlin1 = new Perlin1();
		var p1Node:TreeNode = new TreeNode("Joy", p1Vis);
		
		visNodes.children.addItem(p1Node);		
	
		var p2Vis:Perlin2 = new Perlin2();
		var p2Node:TreeNode = new TreeNode("Plans", p2Vis);
		
		visNodes.children.addItem(p2Node);	
		
		/* album art node */
		var albumViz:AlbumArtVisualizer = new AlbumArtVisualizer();
			albumNode = new TreeNode("Album Art", albumViz);
		
		albumNode.icon = albumArtIcon;
		
		exploreNode.children.addItem(albumNode);
		
		registerForCurrentSong(albumViz);			
		
		/* Lyrics Node */
		var wikiLyrics:LyricWikiTreeNode = new LyricWikiTreeNode("Lyrics");
			exploreNode.children.addItem(wikiLyrics);
			
		registerForCurrentSong(wikiLyrics);			
	
		/* Artist Info Node */
		var artistInfo:ArtistInfoNode = new ArtistInfoNode("Artist Info");
			exploreNode.children.addItem(artistInfo);
			
		registerForCurrentSong(artistInfo);			
		
		
		/* Album Info Node */
		var albumInfo:AlbumInfoNode = new AlbumInfoNode("Album Info");
			exploreNode.children.addItem(albumInfo);
			
		registerForCurrentSong(albumInfo);			
		
		/* Song Info Node */
		var songInfo:SongInfoNode = new SongInfoNode("Song Info");
			exploreNode.children.addItem(songInfo);
			
		registerForCurrentSong(songInfo);			
		
		/* Flickr Node */
		var fVis:FlickrVisualizer = new FlickrVisualizer();
		var flickr:TreeNode = new TreeNode("Flickr", fVis);
		
		flickr.icon = flckrIcon;
		
		exploreNode.children.addItem(flickr);
		
		registerForCurrentSong(fVis);
		
	var relNode:RelatedTreeNode = new RelatedTreeNode("Related Artists");

		exploreNode.children.addItem(relNode);
	registerForCurrentSong(relNode);	
		
		
		
	ac.addItem(libNode);
	ac.addItem(exploreNode);
	ac.addItem(visNodes);
	
	tree.dataProvider = ac;	
	tree.validateNow();
	
	tree.expandItem(visNodes, true);
	tree.expandItem(exploreNode, true);
	
	tree.selectedItem = libNode;
					
	tree.addEventListener(Event.CHANGE, onNavigationTreeClick);		
}

private function onViewAlbumArt(e:AlbumViewEvent):void
{
	tree.selectedItem = albumNode;
	displayNode(albumNode);
}

private function setUpListeners():void
{
	player.addEventListener(MP3PlayerEvent.SONGCOMPLETE, onSoundComplete);
	player.addEventListener(MP3PlayerEvent.SONGPLAY, onSongPlay);
	player.addEventListener(MP3PlayerEvent.SONGSTOP, onSongStop);
	
	Application.application.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}

private function expandAllTopLevelItemsInTree(tree:Tree):void
{
	var topItems:ArrayCollection = ArrayCollection(tree.dataProvider);
	
	for each(var o:Object in topItems)
	{
		tree.expandItem(o, true);
	}
}

/************************ Song Event Handlers **********************/

private function onPlaySongRequest(event:MediaPlayRequestEvent):void
{
	currentSongDP = ArrayCollection(songView.dataProvider);
	playSong(event.song);
}

/*********************** Player Utils *********************/

private function playPreviousSong():void
{
	var currentSong:Song = player.song;
	
	if(currentSong == null)
	{
		songView.selectPreviousSong();
		return;
	}
	
	var index:int = currentSongDP.getItemIndex(currentSong);
	
	if((player.position < BACK_LIMIT) && (index != 0))
	{
		var autoPlay:Boolean = player.playing;
		playSong(Song(currentSongDP.getItemAt(--index)), autoPlay);
	}
	else
	{
		player.restart();
	}			
}

private function playNextSong(autoPlay:Boolean = false):void
{
	var currentSong:Song = player.song;
	
	if(currentSong == null)
	{
		songView.selectNextSong();
		return;
	}

	var index:int = currentSongDP.getItemIndex(currentSong);
	
	if(index == (currentSongDP.length - 1))
	{
		//we are at end of list. stop playing
		//todo: add preference on whether to stop or wrap
		player.stop();		
	}
	else
	{
		var ap:Boolean = (autoPlay)? true : player.playing;
		playSong(Song(currentSongDP.getItemAt(++index)), ap);
	}
}

private function pauseSong():void
{
	player.pause();
}

private function playSong(song:Song, autoPlay:Boolean = true):void
{
	if(song == null)
	{
		return;
	}
	
	if(song != currentSong)
	{
		currentSong = song;
	}
	
	var metaPopulator:SongMetaDataPopulator = new SongMetaDataPopulator(song, settings.amazonAPIKey);
	metaPopulator.loadMetaData();
	
	player.play(song, autoPlay);
}

private function playOrResumeSong():void
{
	if(player.song != null)
	{
		playSong(player.song);
	}
	else
	{
		currentSongDP = songView.dataProvider;
		playSong(songView.selectedSong);
	}	
}

/******************* Player Handlers ********************/

private function onSoundComplete(event:Event):void
{
	playNextSong(true);
}

private function onSongPlay(event:MP3PlayerEvent):void
{
	playerControls.playState = PlayerControls.PLAY;
}

private function onSongStop(event:MP3PlayerEvent):void
{
	playerControls.playState = PlayerControls.PAUSE;
}

/************************ Player Control Handlers *******************/

public function onControlsPrevious(event:PlayerControlEvent):void
{
	playPreviousSong();
}


public function onControlsNext(event:PlayerControlEvent):void
{
	playNextSong();
}
	
public function onControlsPause(event:PlayerControlEvent):void
{
	pauseSong();
}	
				
public function onControlsPlay(event:PlayerControlEvent):void
{
	playOrResumeSong();
}

/************************ UI Handlers **************************/



private function onNavigationTreeClick(event:Event):void
{
	var node:TreeNode = TreeNode(tree.selectedItem);
	displayNode(node);
}

private function displayNode(node:TreeNode):void
{
	if(node == null)
	{
		return;
	}
	
	if(tree.getParentItem(node) is RelatedTreeNode)
	{
		displayView(songView);
		songView.setSearchTerm(node.label, true, false, false);
		
		return;
	}
	
	if(node.data == null)
	{
		return;
	}	
	
	var view:UIComponent = UIComponent(node.data);
	
	displayView(view);	
}

private function displayView(view:UIComponent):void
{
	if(contentContainer.currentView == view)
	{
		return;
	}
	
	contentContainer.currentView = view;	
}

/**************Keyboard Event Handlers****************/
private function onKeyUp(event:KeyboardEvent):void
{
	var keyCode:Number = event.keyCode;
	
	switch(keyCode)
	{
		//right arrow
		case 39:
		{
			playNextSong();
			break;
		}
		//left arrow
		case 37:
		{
			playPreviousSong();
			break;
		}
		//space bar
		case 32:
		{

			if(player.playing)
			{
				pauseSong();
			}
			else
			{
				if(player.song != null)
				{
					playSong(player.song);
				}
				else
				{
					currentSongDP = songView.dataProvider;
					playSong(songView.selectedSong);
				}
			}
			break;
		}										
	}
}

/************* PopUp Handlers *************/

private function onItunesImport(event:MouseEvent):void
{
	var p:IFlexDisplayObject = PopUpManager.createPopUp(this, ITunesImportPanel, true);
	p.addEventListener(Event.CLOSE, onItunesImportClose);
	p.addEventListener(ImportEvent.IMPORT_COMPLETE, onItunesImportComplete);
	PopUpManager.centerPopUp(p);
}

private function onItunesImportComplete(event:ImportEvent):void
{
	library.addSongs(event.songs);
	library.save();
	
	//todo: remove event listeners?
		
	songView.dataProvider = library.songs;
}

private function onItunesImportClose(event:Event):void
{
	closePopup(IFlexDisplayObject(event.target));
}

private function aboutBoxClick():void
{
	var p:IFlexDisplayObject = PopUpManager.createPopUp(this, AboutBox, true);
	p.addEventListener(Event.CLOSE, onAboutBoxClose);
	PopUpManager.centerPopUp(p);
}

private function onAboutBoxClose(event:Event):void
{
	closePopup(IFlexDisplayObject(event.target));
}

private function onSettingsClick():void
{
	var p:IFlexDisplayObject = PopUpManager.createPopUp(this, SettingsView, true);
	p.addEventListener(Event.CLOSE, onSettingsClose);
	p.addEventListener(SettingsEvent.CLEAR_ALBUM_ART, onClearAlbumArt);
	p.addEventListener(SettingsEvent.CLEAR_SONG_LIBRARY, onClearSongLibrary);
	p.addEventListener(SettingsEvent.SETTINGS_CHANGED, onSettingsChanged);
	
	SettingsView(p).settings = settings;
	PopUpManager.centerPopUp(p);
}

private function displayTips():void
{
	//todo: move tip location to setting?
	var tipManager:LocalTipManager = new LocalTipManager(File.appResourceDirectory.resolve(TIPS_DIR_NAME));	
	
	if(tipManager.count <= 0)
	{
		//there are no tips to display
		return;
	}	
	
	
	var p:IFlexDisplayObject = PopUpManager.createPopUp(this, TipsView, true);
	p.addEventListener(Event.CLOSE, onTipsClose);
	//p.addEventListener(SettingsEvent.SETTINGS_CHANGED, onSettingsChanged);
	
	var t:TipsView = TipsView(p);
	
	t.tipManager = tipManager;
	t.showTipsOnStartUp = settings.showTipsOnStart;
	t.addEventListener(TipEvent.SHOW_ON_START_CHANGE, onShowOnStartChange);
	PopUpManager.centerPopUp(p);	
}

private function onShowOnStartChange(e:TipEvent):void
{
	settings.showTipsOnStart = e.showTipsOnStartUp;
	saveSettings();
}

private function onTipsClose(event:Event):void
{
	closePopup(IFlexDisplayObject(event.target));
}

private function closePopup(p:IFlexDisplayObject):void
{
	PopUpManager.removePopUp(p);
}

private function onSettingsChanged(event:SettingsEvent):void
{
	updateSettings(event.newSettings);
	saveSettings();
}

private function updateSettings(newSettings:Settings):Boolean
{
	var settingsChanged:Boolean = false;
	
	if(newSettings.itunesAudioMpegImportString != settings.itunesAudioMpegImportString)
	{
		settings.itunesAudioMpegImportString = newSettings.itunesAudioMpegImportString;
		settingsChanged = true;
	}
	
	if(newSettings.amazonAPIKey != settings.amazonAPIKey)
	{
		settings.amazonAPIKey = newSettings.amazonAPIKey;
		settingsChanged = true;
	}
	
	if(newSettings.flickrAPIKey != settings.flickrAPIKey)
	{
		settings.flickrAPIKey = newSettings.flickrAPIKey;
		settingsChanged = true;
	}	
	
	return settingsChanged;
}

private function onClearAlbumArt(event:SettingsEvent):void
{
	var c:URLCache = new URLCache(AscensionCacheEnum.ALBUM_ART);
		c.clearCache();
		
		library.clearSongPaths();
}

private function onTipsClick():void
{
	displayTips();
}

private function onClearSongLibrary(event:SettingsEvent):void
{
	library.removeAll();	
}

private function onSettingsClose(event:Event):void
{
	closePopup(IFlexDisplayObject(event.target));
}

